package com.example.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result;
import com.example.entity.DeviceGroup;
import com.example.entity.DeviceImage;
import com.example.service.DeviceGroupService;
import com.example.service.DeviceImageService;
import com.example.vo.DeviceImageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 设备图片管理控制器
 */
@RestController
@RequestMapping("/device-image")
@Slf4j
public class DeviceImageController {

    @Resource
    private DeviceImageService deviceImageService;

    @Resource
    private DeviceGroupService deviceGroupService;

    // 文件上传目录
    private static final String UPLOAD_DIR = "uploads/device-images/";

    /**
     * 分页查询设备图片
     */
    @GetMapping("/page")
    public Result<Page<DeviceImageVO>> getImagePage(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String imageName,
            @RequestParam(required = false) Long groupId) {
        try {
            Page<DeviceImage> pageParam = new Page<>(page, size);
            
            LambdaQueryWrapper<DeviceImage> queryWrapper = new LambdaQueryWrapper<>();
            if (imageName != null && !imageName.trim().isEmpty()) {
                queryWrapper.like(DeviceImage::getImageName, imageName.trim());
            }
            if (groupId != null && groupId > 0) {
                queryWrapper.eq(DeviceImage::getGroupId, groupId);
            }
            queryWrapper.orderByDesc(DeviceImage::getCreateTime);

            Page<DeviceImage> result = deviceImageService.page(pageParam, queryWrapper);

            // 转换为VO并填充分组信息
            Page<DeviceImageVO> voPage = new Page<>();
            BeanUtils.copyProperties(result, voPage);

            List<DeviceImageVO> voList = result.getRecords().stream().map(image -> {
                DeviceImageVO vo = new DeviceImageVO();
                BeanUtils.copyProperties(image, vo);

                // 获取分组信息
                DeviceGroup group = deviceGroupService.getById(image.getGroupId());
                if (group != null) {
                    vo.setGroupName(group.getGroupName());
                }

                return vo;
            }).collect(Collectors.toList());

            voPage.setRecords(voList);
            return Result.success(voPage);
        } catch (Exception e) {
            log.error("分页查询设备图片失败", e);
            return Result.error("分页查询设备图片失败");
        }
    }

    /**
     * 根据ID获取设备图片详情
     */
    @GetMapping("/{id}")
    public Result<DeviceImageVO> getImageDetail(@PathVariable String id) {
        try {
            DeviceImage image = deviceImageService.getById(id);
            if (image == null) {
                return Result.error("设备图片不存在");
            }

            DeviceImageVO vo = new DeviceImageVO();
            BeanUtils.copyProperties(image, vo);

            // 获取分组信息
            DeviceGroup group = deviceGroupService.getById(image.getGroupId());
            if (group != null) {
                vo.setGroupName(group.getGroupName());
            }

            return Result.success(vo);
        } catch (Exception e) {
            log.error("获取设备图片详情失败", e);
            return Result.error("获取设备图片详情失败");
        }
    }

    /**
     * 上传设备图片
     */
    @PostMapping("/upload")
    public Result<DeviceImageVO> uploadImage(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "groupId", defaultValue = "1") Long groupId) {
        try {
            // 检查文件
            if (file.isEmpty()) {
                return Result.error("请选择要上传的文件");
            }

            // 检查文件类型
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                return Result.error("文件名不能为空");
            }

            String fileExtension = getFileExtension(originalFilename);
            if (!isValidImageType(fileExtension)) {
                return Result.error("只支持SVG、PNG、JPG格式的图片");
            }

            // 检查文件大小（2MB）
            if (file.getSize() > 2 * 1024 * 1024) {
                return Result.error("文件大小不能超过2MB");
            }

            // 检查分组是否存在
            DeviceGroup group = deviceGroupService.getById(groupId);
            if (group == null) {
                return Result.error("设备分组不存在");
            }

            // 创建上传目录
            Path uploadPath = Paths.get(UPLOAD_DIR);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 生成唯一文件名
            String fileName = UUID.randomUUID().toString() + "." + fileExtension;
            Path filePath = uploadPath.resolve(fileName);

            // 保存文件
            Files.copy(file.getInputStream(), filePath);

            // 保存到数据库
            DeviceImage deviceImage = new DeviceImage();
            deviceImage.setImageName(originalFilename);
            deviceImage.setFileName(fileName);
            deviceImage.setFilePath(filePath.toString());
            deviceImage.setFileSize(file.getSize());
            deviceImage.setFileType(file.getContentType());
            deviceImage.setImageUrl("/api/device-image/" + fileName + "/view");
            deviceImage.setGroupId(groupId);

            boolean success = deviceImageService.save(deviceImage);
            if (success) {
                DeviceImageVO vo = new DeviceImageVO();
                BeanUtils.copyProperties(deviceImage, vo);
                vo.setGroupName(group.getGroupName());
                return Result.success(vo);
            } else {
                // 删除已上传的文件
                Files.deleteIfExists(filePath);
                return Result.error("保存设备图片失败");
            }
        } catch (Exception e) {
            log.error("上传设备图片失败", e);
            return Result.error("上传设备图片失败");
        }
    }

    /**
     * 更新设备图片信息
     */
    @PutMapping
    public Result<DeviceImageVO> updateImage(@RequestBody DeviceImage image) {
        try {
            // 检查图片是否存在
            DeviceImage existingImage = deviceImageService.getById(image.getId());
            if (existingImage == null) {
                return Result.error("设备图片不存在");
            }

            // 检查分组是否存在
            DeviceGroup group = deviceGroupService.getById(image.getGroupId());
            if (group == null) {
                return Result.error("设备分组不存在");
            }

            // 检查图片名称是否重复（排除自己）
            long count = deviceImageService.count(
                new LambdaQueryWrapper<DeviceImage>()
                    .eq(DeviceImage::getImageName, image.getImageName())
                    .ne(DeviceImage::getId, image.getId())
            );
            if (count > 0) {
                return Result.error("图片名称已存在");
            }

            boolean success = deviceImageService.updateById(image);
            if (success) {
                DeviceImageVO vo = new DeviceImageVO();
                BeanUtils.copyProperties(image, vo);
                vo.setGroupName(group.getGroupName());
                return Result.success(vo);
            } else {
                return Result.error("更新设备图片失败");
            }
        } catch (Exception e) {
            log.error("更新设备图片失败", e);
            return Result.error("更新设备图片失败");
        }
    }

    /**
     * 删除设备图片
     */
    @DeleteMapping("/{id}")
    public Result<Void> deleteImage(@PathVariable String id) {
        try {
            // 检查图片是否存在
            DeviceImage image = deviceImageService.getById(id);
            if (image == null) {
                return Result.error("设备图片不存在");
            }

            // 删除文件
            Path filePath = Paths.get(image.getFilePath());
            Files.deleteIfExists(filePath);

            // 删除数据库记录
            boolean success = deviceImageService.removeById(id);
            if (success) {
                return Result.success();
            } else {
                return Result.error("删除设备图片失败");
            }
        } catch (Exception e) {
            log.error("删除设备图片失败", e);
            return Result.error("删除设备图片失败");
        }
    }

    /**
     * 批量删除设备图片
     */
    @DeleteMapping("/batch")
    public Result<Void> batchDeleteImages(@RequestBody List<Long> ids) {
        try {
            // 获取所有图片信息
            List<DeviceImage> images = deviceImageService.listByIds(ids);
            
            // 删除文件
            for (DeviceImage image : images) {
                Path filePath = Paths.get(image.getFilePath());
                Files.deleteIfExists(filePath);
            }

            // 批量删除数据库记录
            boolean success = deviceImageService.removeByIds(ids);
            if (success) {
                return Result.success();
            } else {
                return Result.error("批量删除设备图片失败");
            }
        } catch (Exception e) {
            log.error("批量删除设备图片失败", e);
            return Result.error("批量删除设备图片失败");
        }
    }

    /**
     * 下载设备图片
     */
    @GetMapping("/{id}/download")
    public void downloadImage(@PathVariable String id, HttpServletResponse response) {
        try {
            DeviceImage image = deviceImageService.getById(id);
            if (image == null) {
                response.setStatus(404);
                return;
            }

            File file = new File(image.getFilePath());
            if (!file.exists()) {
                response.setStatus(404);
                return;
            }

            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + image.getImageName() + "\"");
            response.setContentLength((int) file.length());

            // 写入响应流
            try (FileInputStream fis = new FileInputStream(file);
                 OutputStream os = response.getOutputStream()) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    os.write(buffer, 0, length);
                }
                os.flush();
            }
        } catch (Exception e) {
            log.error("下载设备图片失败", e);
            response.setStatus(500);
        }
    }

    /**
     * 查看设备图片
     */
    @GetMapping("/{fileName}/view")
    public void viewImage(@PathVariable String fileName, HttpServletResponse response) {
        try {
            Path filePath = Paths.get(UPLOAD_DIR, fileName);
            File file = filePath.toFile();
            
            if (!file.exists()) {
                response.setStatus(404);
                return;
            }

            // 根据文件扩展名设置Content-Type
            String extension = getFileExtension(fileName);
            String contentType = getContentType(extension);
            response.setContentType(contentType);

            // 写入响应流
            try (FileInputStream fis = new FileInputStream(file);
                 OutputStream os = response.getOutputStream()) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    os.write(buffer, 0, length);
                }
                os.flush();
            }
        } catch (Exception e) {
            log.error("查看设备图片失败", e);
            response.setStatus(500);
        }
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        return lastDotIndex > 0 ? fileName.substring(lastDotIndex + 1).toLowerCase() : "";
    }

    /**
     * 检查是否为有效的图片类型
     */
    private boolean isValidImageType(String extension) {
        return "svg".equals(extension) || "png".equals(extension) || 
               "jpg".equals(extension) || "jpeg".equals(extension);
    }

    /**
     * 根据文件扩展名获取Content-Type
     */
    private String getContentType(String extension) {
        switch (extension.toLowerCase()) {
            case "svg":
                return "image/svg+xml";
            case "png":
                return "image/png";
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            default:
                return "application/octet-stream";
        }
    }
} 